package ar.com.spsolutions.splibrary.services.google.books;

import java.io.InputStream;
import java.io.Serializable;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.security.access.annotation.Secured;

import ar.com.spsolutions.splibrary.book.Book;
import ar.com.spsolutions.splibrary.general.RoleConverterService;
import ar.com.spsolutions.splibrary.services.BookService;
import ar.com.spsolutions.splibrary.services.exception.ServiceException;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class GoogleBookService implements Serializable {

	private static final long serialVersionUID = -9077418873030417905L;

	private transient Gson gson;

	private BookService bookService;

	public GoogleBookService() {
		super();
	}

	public GBookResultForISBN search(final String searchValue) {
		return this.getGson().fromJson(this.stringSearchResult(searchValue),
				GBookResultForISBN.class);
	}

	private String stringSearchResult(final String searchValue) {
		final DefaultHttpClient httpclient = new DefaultHttpClient();
		final HttpContext localContext = new BasicHttpContext();
		final HttpGet httpget = new HttpGet(
				"https://www.googleapis.com/books/v1/volumes?q=isbn:"
						+ searchValue
						+ "&fields=items(volumeInfo/title,volumeInfo/authors,volumeInfo/publisher,volumeInfo/categories,volumeInfo/industryIdentifiers,volumeInfo/averageRating,volumeInfo/imageLinks/thumbnail,volumeInfo/description)");
		try {
			httpclient.execute(httpget, localContext);
			localContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
			final HttpResponse response = (HttpResponse) localContext
					.getAttribute(ExecutionContext.HTTP_RESPONSE);
			final HttpEntity entity = response.getEntity();
			final InputStream content = entity.getContent();
			final StringBuilder builder = new StringBuilder();
			int code = content.read();
			while (code > -1) {
				builder.append(Character.valueOf((char) code));
				code = content.read();
			}
			return builder.toString();

		} catch (final Exception e) {
			throw new ServiceException(e);
		}
	}

	public GoogleBookService(final BookDeserializer bookDeserializer) {
		final GsonBuilder gsonBuilder = new GsonBuilder();
		gsonBuilder.registerTypeAdapter(Book.class, bookDeserializer);
		this.gson = gsonBuilder.create();
	}

	public Gson getGson() {
		return this.gson;
	}

	public void setGson(final Gson gson) {
		this.gson = gson;
	}

	@Secured(RoleConverterService.ROLE_LIBRARIAN)
	public void add(final Book book) {
		this.getBookService().add(book);
	}

	public BookService getBookService() {
		return this.bookService;
	}

	public void setBookService(final BookService bookService) {
		this.bookService = bookService;
	}

}
